[TOC] Je vous en prie.
Que peut faire la plateforme de trading quantique FMZ?
FMZ Quant Trading est la communauté quantitative la plus professionnelle dans le domaine du trading quantitatif. Ici, vous pouvez apprendre, écrire, partager, acheter et vendre des stratégies quantitatives; vous pouvez effectuer des backtests en ligne et utiliser des robots de simulation pour effectuer des transactions simulées; vous pouvez également exécuter, publier et regarder le trading en direct.
Série complète de tutoriels
Des tutoriels graphiques:
En cas de problème, vous pouvez poser des questions et discuter dans le forum à tout moment, ou soumettre un ticket, ou contacter un administrateur dans le groupe Telegram (TélégrammeDans l'ensemble, la réponse à cette question sera rapide.
Appui au ChatGPT pour l'aide au développement
La plateforme de négociation quantitative FMZ a adopté ChatGPT comme outil d'assistance au développement, auquel on peut accéder en cliquant sur
Quels langages de programmation sont disponibles pour mettre en œuvre mes stratégies?
La plateforme de négociation de FMZ Quant prend en charge l'utilisationJavaScript
, TypeScript
, Python
, C++
, Pine
Mylanguage
etBlockly Visualization
pour écrire et concevoir des stratégies.
Il soutientTypeScript
Le langage, toujours réglé surJavaScript
la stratégie quand nous créons des stratégies, alors nous écrivons// @ts-check
au début du code de stratégie ou cliquez sur le boutonTypeScript
dans le coin supérieur droit de la zone d'édition de la stratégie pour passer àTypeScript
La plateforme reconnaîtra le code commeTypeScript
automatiquement et vous fournir le support approprié de compilation et de vérification de type pour:
TypeScript
La fonction de vérification de type statique peut vous aider à trouver des erreurs potentielles lors de l'écriture de code et à améliorer la qualité du code.TypeScript
Le système de type de Microsoft permet de trouver plus rapidement les attributs et les méthodes dont vous avez besoin lors de l'écriture de code, améliorant ainsi l'efficacité du développement.TypeScript
, vous pouvez mieux organiser et maintenir votre code, ce qui le rend facile à lire et à comprendre.TypeScript
fournit de puissantes fonctionnalités de programmation orientée objet, telles que des interfaces, des classes, des génériques, etc., vous aidant à écrire un code de stratégie plus robuste et réutilisable.Vous n'avez besoin que de maîtriser un de ces langages. En plus de soutenir la façon de concevoir des stratégies en écrivant du code, vous pouvez également créer des stratégies à l'aide de modules visuels (Blockly).
Blockly
Tutoriels de visualisation:
Mettez le
Python
interprète utilisé par lePython
programme stratégique
Des stratégies écrites enPython
, lors du backtesting ou de la négociation en direct, si l'environnement du système docker a à la foisPython2etPython3installé, vous pouvez régler lePython
La version à lancer en temps d'exécution sur la première ligne de la stratégie, telle que#!python3
et#!python2
Vous pouvez également spécifier un chemin absolu, comme:#!/usr/bin/python3
.
Qu'est-ce que le Docker?
Docker peut être compris comme l'exécuteur de votre stratégie de trading, responsable des demandes de données complexes, de la réception de données, des liens réseau, du postback de journaux, etc. Le docker fonctionne sur votre serveur, même si le site Web de la plateforme de trading FMZ Quant a une panne de réseau, cela n'affectera pas le fonctionnement de votre docker. Le docker peut fonctionner surLe système Linux, Les fenêtres, Mac OS, Pour Android, Raspberry Pi ARM sous Linuxet autres systèmes.Page Docker, Installation et mise à jour des étapes de docker Linux. Les robots et les journaux gérés par le docker sont stockés dans le répertoire/logs/storage
Le dossier est unSqlite
fichier de base de données avecdb3
, qui peut être édité directement par leSqlite
Pour un fichier avec une extensiondb3
Dans la vraie base de données de bots, le nom du fichier est l'ID du bot.
Protocoles pris en charge
Lorsque les stratégies de trading sont développées sur la plateforme de trading FMZ Quant, le contenu de la stratégie n'est visible que par les titulaires de compte FMZ.Python
Le code de stratégie est chargé dans le package, de sorte que la localisation du contenu de la stratégie puisse être réalisée.
La sécurité desPython
Le code:
Parce que...Python
est un langage open-source qui est extrêmement facile à décompiler, si la stratégie n'est pas pour un usage personnel mais pour la location, vous pouvez exécuter la stratégie sur votre propre docker déployé et la louer sous forme de sous-compte ou de gestion complète du docker si vous craignez une fuite de stratégie.
Le chiffrement dePython
code de stratégie:
Par défaut,Python
Le code de stratégie n'est pas chiffré lorsqu'il est utilisé par l'auteur et chiffré lorsqu'il est loué à d'autres.
En modifiant le code suivant au début duPython
La stratégie, vous pouvez spécifier si le code de la stratégie à chiffrer pour un usage personnel ou de location.Python
Les versions qui prennent en charge le chiffrement des codes de stratégie sont les suivantes:Python 2.7
, Python 3.5
etPython 3.6
.
#!python
comme la version de l'interpréteur Python, puis utiliser,
pour garder à l'écart; entrez la commande de chiffrementencrypt
Si vous ne précisez pas la version dePython
, ajouter#!,encrypt
directly. #!python,encrypt
Ou alors...
#!encrypt
#!python, not encrypted
Ou alors...
#!not encrypted
Utiliser le codeos.getenv('__FMZ_ENV__')
pour déterminer si le code de chiffrement est valide; le retour de la chaîne"encrypt"
indique qu'il a pris effet. Il est valable uniquement dans le bot réel, et le backtest ne chiffrera pas lePython
les codes stratégiques.
#!encrypt
def main():
ret = os.getenv('__FMZ_ENV__')
# If the print variable ret is the string "encrypt" or ret == "encrypt" is true, that means the encryption is valid.
Log(ret, ret == "encrypt")
Les données sensibles, telles que les informations de compte et les chaînes cryptées dans les paramètres de stratégie configurés sur la plate-forme de trading FMZ Quant, sont cryptées dans le navigateur Web. Toutes les informations stockées sur la plate-forme de trading FMZ Quant sont cryptées (pas de données en texte brut), et seuls les utilisateurs peuvent déchiffrer et utiliser les informations, ce qui améliore considérablement la sécurité des données sensibles. Veuillez ne pas divulguer ou vendre les stratégies si d'autres informations sensibles sont incluses dans le code de stratégie, les paramètres et les descriptions de stratégie, etc.
RSA KEY
méthode d'authentification de l'échange comme exemple pour expliquer en détail comment configurer les informations sensibles localement sur l'appareil où se trouve le programme docker.PKCS#8
, il existe de nombreux outils de création, tels queopenssl
.RSA KEY
sur l'échange, et télécharger la clé publique créée dansÉtape 1pendant la création.txt
file, ou dans d'autres chemins dans le répertoire du programme docker.RSA KEY
créé par l'échange dans la zone d'édition de la configurationAccess Key
.txt
le fichier placé dans le même répertoire de niveau du docker dans leÉtape 3dans la zone d'édition de la configurationSecret Key
. Par exemple, si le nom du fichier est:rsaKey.txt
, et le fichier et le docker sont remplis dans le même répertoire de niveau:file:///rsaKey.txt
. Si le fichier est dans le répertoire à côté du répertoire du programme dockerrsa_key
, remplir:file:///rsa_key//rsaKey.txt
Si vous placezrsaKey. txt
Dans le cas d'un fichier situé ailleurs sur votre ordinateur ou serveur, suivez ces instructions en conséquence, il convient de noter que ce fichier ne peut être placé que dans des répertoires de même niveau ou des sous-répertoires par rapport à Docker.Cela rend plus sûr pour localiser et enregistrer la clé privée, vous pouvez vous référer àVidéo explicativepour un processus détaillé.
Qu'est-ce qu'un système de backtest, et à quoi sert-il?
Après avoir réalisé la conception d'une stratégie de trading quantitative, comment pouvez-vous connaître la situation de base de votre stratégie, telle que la logique de la stratégie et la direction des rendements de la stratégie? Bien sûr, nous ne pouvons pas utiliser de l'argent réel directement pour exécuter la stratégie sur le marché de trading réel, mais nous pouvons utiliser des données historiques pour tester votre stratégie et connaître les profits de votre stratégie dans les données historiques.
Les données du système de backtest sont-elles exactes et quelle est l'exactitude des résultats des backtest?
FMZ Quant Trading plateforme divise le système de backtest enniveau réel du marchéetniveau de simulationLe niveau réel du marché est de backtest complètement selon les données historiques complètes; tandis que le niveau de simulation backtest génèretick
Les données sont basées sur les données historiques réelles, mais les données au niveau du marché réel sont plus précises et les résultats sont plus crédibles.Description du mécanisme de contre-test FMZCependant, le backtesting n'est que la performance de la stratégie selon les données historiques. Les données historiques ne peuvent pas représenter pleinement le marché futur. Le marché historique peut se répéter, ou cela peut également conduire au cygne noir. Par conséquent, les résultats du backtest doivent être traités de manière rationnelle et objective.
Questions à prendre en compte lors du backtesting de différentes stratégies de langage de programmation:
Le backtest deJavaScriptetC++Les stratégies de trading est menée dans le navigateur, et le vrai marché bot ouNous avons une application.Le marché réel de change émulé (c'est-à-dire leNous avons une application.L'échange émulé de la plateforme de trading FMZ Quant) s'exécute sans installer aucun autre logiciel, bibliothèques ou modules. Le backtest dePythonL'opération de marché réelle et le backtest dépendent tous deux de la capacité de l'utilisateur à effectuer des tests sur les marchés.PythonSi certaines bibliothèques sont nécessaires, elles doivent être installées manuellement (seules les bibliothèques communes sont prises en charge sur les serveurs publics).
Données de contre-test dans le système
Il existe deux types de backtest de la plateforme de trading FMZ Quant: le backtest au niveau de la simulation et le backtest au niveau du marché réel.tick
Chaque période de ligne K générera 12 points de temps de backtesting; cependant, le niveau réel du marché recueilleticks
Le mécanisme de backtest de FMZ permet à la stratégie de trading de négocier plusieurs fois sur une seule ligne K, évitant la situation où le trading ne peut être exécuté qu'au prix de clôture. Il est plus précis tout en tenant compte de la vitesse de backtest. Pour des explications plus détaillées, veuillez vous référer àle lien.
Méthode de débogage de la stratégie dans le système de backtesting
Débogage des tests de stratégie JavaScript dans Chrome DevTools
Monnaie cryptée (Cryptocurrency)
Nom | Le type | Instruction |
---|---|---|
Bitfinex | objet de change au comptant | le soutien de paires de négociation limitées, telles que:BTC_USD , ETH_USD etLTC_USD , etc. (notez que la devise de cotation des paires de négociation estUSD dollars américains) |
Binance | objet de change au comptant | le soutien de paires de négociation limitées, telles que:BTC_USDT , ETH_USDT , ETH_BTC etLTC_BTC , etc. |
- Ça va. | objet de change au comptant | le soutien de paires de négociation limitées, telles que:BTC_USDT , ETH_USDT , ETH_BTC etLTC_BTC , etc. |
Huobi est un joueur. | objet de change au comptant | le soutien de paires de négociation limitées, telles que:BTC_USDT , ETH_USDT , ETH_BTC etLTC_BTC , etc. |
Les titres à terme | Objet d'échange à terme | le soutien de paires de négociation limitées, telles que:BTC_USD etETH_USD , etc.; la devise de cotation des paires de négociation estUSD ; après la définition du code de contrat spécifique (voir la fonctionexchange.SetContractType ), le contrat est un contrat à crypto-marge; les codes de contrat pris en charge comprennent:this_week , next_week , quarter etswap |
HuobiDM | Objet d'échange à terme | HuobiDM est Huobi Futures (Huobi Contract), qui prend en charge des paires de négociation limitées, telles que:BTC_USD etETH_USD , etc.; la devise de cotation des paires de négociation estUSD ; après la définition du code de contrat spécifique (voir la fonctionexchange.SetContractType ), le contrat est un contrat à crypto-marge; les codes de contrat pris en charge comprennent:this_week , next_week , quarter etswap . |
BitMEX | Objet d'échange à terme | la paire de négociation estXBT_USD ; après la définition du code de contrat spécifique (voir la fonctionexchange.SetContractType ), le contrat est un contrat cryptographique à marge; le code du contrat pris en charge est:XBTUSD |
Les contrats à terme de Binance | Objet d'échange à terme | le soutien de paires de négociation limitées, telles que:BTC_USDT etETH_USDT , etc.; la devise de cotation des paires de négociation estUSD ; après la définition du code de contrat spécifique (voir la fonctionexchange.SetContractType ), le contrat est uneUSDT - contrat à marge; le code du contrat pris en charge estswap |
Options dérivées | Objet d'échange à terme | les paires de négociation sont:BTC_USD etETH_USD ; après la définition du code de contrat spécifique (voir la fonctionexchange.SetContractType ), le contrat est un contrat à crypto-marge; des codes spécifiques des contrats d'options doivent être définis |
Pour les objets d'échange de contrats à terme dans le système de backtest, le changement de paires de négociation n'est pas temporairement pris en charge dans les codes de stratégie.
Le backtest de niveau de simulation est basé sur les données de ligne K sous-jacentes du système de backtest, simulant les données de tick dans le cadre des valeurs du prix le plus élevé, le prix le plus bas, le prix d'ouverture et le prix de clôture d'une barre de ligne K sous-jacente donnée selon un certain algorithme.tick
les données lorsque l'interface est demandée. Pour plus de détails, veuillez vous référer à:Description du mécanisme de contre-test au niveau de simulation quantique FMZ.
Le backtest au niveau du marché réel est letick
Pour les stratégies basées sur lestick
Dans le cas des tests antérieurs de niveau de marché réel, les données de niveau de marché réel utilisées pour le backtest sont plus proches de la réalité.tick
Les données sont des données enregistrées réelles, pas simulées. Il prend en charge les données de profondeur, la lecture des données d'enregistrement des transactions sur le marché, la profondeur personnalisée et chaque donnée de négociation individuelle. La taille maximale du backtest de données au niveau du marché réel est maximale de 50 Mo, sans limite sur la plage de temps de backtest dans la limite supérieure de l'ensemble de données. Si vous avez besoin d'agrandir la plage de temps de backtest autant que possible, vous pouvez réduire la valeur de l'équipement de réglage de profondeur d'appel et ne pas utiliser chaque donnée de négociation individuelle pour augmenter la plage de temps de backtest.GetDepth
,GetTrades
Dans un moment de données de marché sur la chronologie, appelantGetTicker
,GetTrades
, GetDepth
etGetRecords
Ne pas pousser le temps plusieurs fois lorsque le temps se déplace sur la chronologie du backtest (ce qui ne déclenchera pas un saut vers le prochain moment des données du marché). Les appels répétés à l'une des fonctions ci-dessus pousseront le temps du backtest pour se déplacer sur la chronologie du backtest (sauter vers le prochain moment des données du marché). Lorsque le niveau réel du marché est utilisé pour le backtest, il n'est pas recommandé de choisir un moment antérieur. Il peut ne pas y avoir de données au niveau du marché réel dans la période de temps prématurée.
Le backtest au niveau du marché réel soutient actuellement:
La fonction d'optimisation des paramètres du système de backtest de la plateforme de trading FMZ Quant consiste à définir des optimisations en fonction de chaque option d'optimisation des paramètres pendant le backtest, et les options sont indiquées comme suit:
Générer des combinaisons de paramètres, et traverser toutes ces combinaisons à backtest (à savoir backtesting chaque combinaison de paramètres une fois).NuméroLe système de backtesting permet d'optimiser le type de données.
Par exemple, définissez les options d'optimisation des paramètres sur la page de backtest:
Le backtest du mode d'optimisation des paramètres:
Dans la page d'édition de stratégie, dans la pagination de
PrenezJavaScript
la stratégie comme exemple, et cliquez sur
Il y a de légères différences sur JavaScript
, Python
, cpp
etMylanguage
:
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
- Je ne sais pas.
(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
platforms: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*)
Le système utilise lesGET
méthode pour demander une URL personnalisée (URL accessible au public) afin d'obtenir une source de données externe pour le backtest.
Paramètre | Signification | Expliquer |
---|---|---|
Le symbole | Nom du symbole | comme BTC_USD_OKCoin_EN |
Le jour de l'Aïd | Les échanges | comme OKCoin_EN |
Ronde | Précision des prix | tel que 3, le prix dans les données renvoyées doit être multiplié par 1000 et arrondi |
Environs | Précision de la quantité | comme 2, le montant des données renvoyées doit être multiplié par 100 et arrondi |
Période | Période de barre (millièmes de seconde) | Par exemple, 60 000 indiquant la barre demandant une minute |
Profondeur | Niveaux de profondeur | 1-20 |
Commerces | Si les données doivent être scindées | vrai/faux |
- Je ne sais pas. | Heure de début | Le timestamp est unix |
Pour | Le temps de la fin | Le timestamp est unix |
Note: le numéro de série
Round and V-Round are two parameters designed to avoid losing the precision of floating-point numbers during network transmission. The price data, trading volume and order amount, are all transmitted using integers.
Exemple de données cousues:
http://customserver:80/data?symbol=BTC_USD_OKCoin_EN&eid=OKCoin_EN&round=3&vround=3&period=900000&from=1564315200&to=1567267200
Le format retourné doit être l'un des deux formats suivants (qui seront automatiquement reconnus par le système):
Test de retour ordinaire au niveau des barres
{
"schema":["time","open","high","low","close","vol"],
"data":[[1564315200000,9531300,9531300,9497060,9497060,787],[1564316100000,9495160,9495160,9474260,9489460,338]]
}
Données de backtest au niveau du tick (y compris les informations sur la profondeur du marché, un tableau avec un format de profondeur de [prix, volume]; il peut y avoir plusieurs niveaux de profondeur;
asks fait référence à l'ordre croissant des prix et bids fait référence à l'ordre inverse des prix).
{
"schema":["time","asks", "bids","trades","close","vol"],
"data":[[1564315200000,[[9531300,10]], [[9531300,10]],[[1564315200000,0,9531300,10]],9497060,787]]
}
Définition
Le champ | Définition |
---|---|
Le schéma | Il spécifie les attributs des colonnes dans le tableau de données, qui est sensible à la casse et est limité à |
Données | Un tableau qui stocke des données par schéma |
Format des données
Le champ | Définition |
---|---|
demandes/offres | [prix, volume],...] |
commerces | [temps, direction, prix, volume,...] |
Fourniture de données sur le taux de financement:
Par exemple, lors du backtesting de Binance Futures, il est nécessaire d'avoir des données supplémentaires sur le taux de financement, qui doivent être fournies par une source de données personnalisée.
{
"detail": {},
"symbol": "futures_binance.eth_usdt.funding",
"schema": ["time", "open", "high", "low", "close", "vol"],
"data": [
[1582876800000, 25289, 25289, 25289, 25289, 0],
[1582905600000, 30522, 30522, 30522, 30522, 0],
[1582934400000, 40998, 40998, 40998, 40998, 0],
...
[1626652800000, 198, 198, 198, 198, 0],
[1626681600000, 691, 691, 691, 691, 0], // The adjacent periodic interval is 8 hours
[1626710400000, 310, 310, 310, 310, 0], // The funding rate of Binance updates every 8 hours, and why the data of the funding rate turns out to be 310?
[1626739200000, 310, 310, 310, 310, 0], // Like the bars data, to avoid losing the precision of floating-point numbers during network transmission, the data uses integer, so the data needs to be processed according to round parameter; the data, returned to the backtest system after processing, is 310
[1626768000000, -41610, -41610, -41610, -41610, 0], // The funding rate might be a negative value
[1626796800000, -5125, -5125, -5125, -5125, 0],
...
[1627977600000, 10000, 10000, 10000, 10000, 0]
]
}
Exemple de demande de données du système de backtest:
http://customserver:80/data?symbol=futures_binance.eth_usdt.funding&eid=Futures_Binance&round=8&vround=5&depth=20&trades=1&custom=0&period=3600000&from=1360771200&to=1628006400
Exemple de source de données personnalisée:
Spécifier la source de données, URL:http://xxx.xx.x.xx:9090/data
Personnalisez le serveur de données, écrit en golang:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
// e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data
// r.URL: /data?depth=20&detail=true&eid=Binance&from=1566820800&period=900000&round=3&symbol=BTC_USDT_Binance&to=1569686400&trades=1&vround=5
// response
defer func() {
// response data
/* e.g. data
{
"schema":["time","open","high","low","close","vol"],
"data":[
[1564315200000,9531300,9531300,9497060,9497060,787],
[1564316100000,9495160,9495160,9474260,9489460,338]
]
}
*/
ret := map[string]interface{}{
"schema" : []string{"time","open","high","low","close","vol"},
"data" : []interface{}{
[]int64{1564315200000,9531300,9531300,9497060,9497060,787},
[]int64{1564316100000,9495160,9495160,9474260,9489460,338},
},
}
b, _ := json.Marshal(ret)
w.Write(b)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
stratégie de test,JavaScript
Exemple:
/*backtest
start: 2019-07-28 00:00:00
end: 2019-07-29 00:00:00
period: 1m
platforms: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
*/
function main() {
var ticker = exchange.GetTicker()
var records = exchange.GetRecords()
Log(ticker)
Log(records)
}
Graphiques dessinés par les données personnalisées du système de backtest:
Stratégie Imprimer des informations:
La plateforme de trading de FMZ Quant est open-source pour leJavaScript
La versionPython
version du moteur de backtest local, réglage de supportPériode sous-jacente de la ligne Kpendant le backtesting.
Touche de raccourci pour basculer entre la stratégie
Utilisez la clé.Ctrl +,
pour revenir à la page Ctrl
Appuie sur la touche.,
.
Touche de raccourci pour la stratégie d'économie
Utilisez la clé.Ctrl + s
pour sauver des stratégies.
Raccourci pour démarrer le backtest de stratégie
Utilisez la clé.Ctrl + b
pour activer
Nom de la fonction | Définition |
---|---|
main() |
C'est une fonction d'entrée. |
onexit() |
Il s'agit d'une fonction de nettoyage lorsque la sortie est normale, son temps d'exécution maximal est de 5 minutes, qui peut être laissé non déclaré.interromprel'erreur sera signalée. |
onerror() |
Il s'agit d'une fonction de sortie anormale, son temps d'exécution maximal est de 5 minutes, ce qui peut être laissé non déclaré.Python etcpp ne supporte pas cette fonction. |
init() |
c'est une fonction d'initialisation, son programme de stratégie sera appelé automatiquement quand il commence à fonctionner, ce qui peut être laissé non déclaré. |
onerror()
.onerror()
est déclenchée dans le bot, la fonctiononexit()
ne sera pas déclenchée.onexit()
, le traitement des travaux de nettoyage, avec un temps d'exécution maximal de 5 minutes, qui est réalisé par l'utilisateur.
function main(){
Log("Start running, stop after 5 seconds, and execute onexit function!")
Sleep(1000 * 5)
}
// onexit function implementation
function onexit(){
var beginTime = new Date().getTime()
while(true){
var nowTime = new Date().getTime()
Log("The program stops counting down..The cleaning starts and has passed:", (nowTime - beginTime) / 1000, "Seconds!")
Sleep(1000)
}
}
import time
def main():
Log("Start running, stop after 5 seconds, and execute onexit function!")
Sleep(1000 * 5)
def onexit():
beginTime = time.time() * 1000
while True:
ts = time.time() * 1000
Log("The program stops counting down..The cleaning starts and has passed:", (ts - beginTime) / 1000, "Seconds!")
Sleep(1000)
void main() {
Log("Start running, stop after 5 seconds, and execute onexit function!");
Sleep(1000 * 5);
}
void onexit() {
auto beginTime = Unix() * 1000;
while(true) {
auto ts = Unix() * 1000;
Log("The program stops counting down..The cleaning starts and has passed:", (ts - beginTime) / 1000, "Seconds!");
Sleep(1000);
}
}
L'utilisateur implémente la fonction d'initialisationinit()
, qui exécutera automatiquement la fonctioninit()
au début de la stratégie pour compléter la tâche d'initialisation.
function main(){
Log("The first line of the code executed in the program!", "#FF0000")
Log("Exit!")
}
// Initialization Function
function init(){
Log("Initialization!")
}
def main():
Log("The first line of the code is executed!", "#FF0000")
Log("Exit!")
def init():
Log("Initialization!")
void main() {
Log("The first line of the code is executed!", "#FF0000");
Log("Exit!");
}
void init() {
Log("Initialization!");
}
Exécution de la fonctiononerror()
Cette fonction ne prend pas en charge les stratégies écrites enPython
etcpp
.
function main() {
var arr = []
Log(arr[6].Close)
}
function onerror() {
Log("error")
}
# not supported by python
// not supported by C++
Dans les stratégies écrites enJavaScript
, Python
etcpp
, leSleep()
Dans le bot, il est utilisé pour contrôler les intervalles de vote de stratégie, et aussi contrôler la fréquence de demande d'accès à l'interface API de l'échange.
Exemples de cadres de base de stratégies de crypto-monnaie:
function onTick(){
//Write strategy logic here, and it will be called constantly, such as printing market information
Log(exchange.GetTicker())
}
function main(){
while(true){
onTick()
//The function "Sleep" is mainly used to control the polling frequency of cryptocurrency strategies to prevent accessing the exchange API interafce too frequently
Sleep(60000)
}
}
def onTick():
Log(exchange.GetTicker())
def main():
while True:
onTick()
Sleep(60000)
void onTick() {
Log(exchange.GetTicker());
}
void main() {
while(true) {
onTick();
Sleep(60000);
}
}
Prenons l'exemple le plus simple, si je veux placer un ordre d'achat avec un prix de 100 et une quantité de 1 sur l'échange chaque seconde, je peux l'écrire comme ceci:
function onTick(){
// It is just an example; for all the assets will be used to place orders fast during backtest or in the bot, do not implement the example in the bot
exchange. Buy(100, 1)
}
function main(){
while(true){
onTick()
// The pause period can be customized in millisecond (1 second = 1000 milliseconds)
Sleep(1000)
}
}
def onTick():
exchange.Buy(100, 1)
def main():
while True:
onTick()
Sleep(1000)
void onTick() {
exchange.Buy(100, 1);
}
void main() {
while(true) {
onTick();
Sleep(1000);
}
}
Lebibliothèque de modèlesest un module de code réutilisable dans la plateforme de trading FMZ Quant, fonctionnant comme une catégorie de codes de stratégie de trading.Bibliothèque de modèles, un modèle est ajouté à la page
JavaScript
:
Python
:
cpp
:
Fonction d'exportation de la bibliothèque de modèles
La fonction d'exportation est une fonction d'interface de
/*
-- This method is called directly with $.Test() after the strategy refers to the template
-- The "main" function will not be triggered in the strategy, and it is only used as the entry point for template debugging
*/
$.Test = function() {
Log('Test')
}
function main() {
$.Test()
}
def Test():
Log("template call")
# Export "Test" function; the main strategy can be called by ext.Test()
ext.Test = Test
// The strategy refers to the template and calls this method directly with ext::Test()
void Test() {
Log("template call");
}
Les paramètres de la bibliothèque de modèles:
Codes de bibliothèque de modèle:
$.SetParam1 = function(p1) {
param1 = p1
}
$.GetParam1 = function() {
Log("param1:", param1)
return param1
}
def SetParam1(p1):
global param1
param1 = p1
def GetParam1():
Log("param1:", param1)
return param1
ext.SetParam1 = SetParam1
ext.GetParam1 = GetParam1
void SetParam1(float p1) {
param1 = p1;
}
float GetParam1() {
Log("param1:", param1);
return param1;
}
Consultez le code de stratégie dans leBibliothèque de modèlesl'exemple mentionné ci-dessus:
function main () {
Log("call $.GetParam1:", $.GetParam1())
Log("call $.SetParam1:", "#FF0000")
$.SetParam1(20)
Log("call $.GetParam1:", $.GetParam1())
}
def main():
Log("call ext.GetParam1:", ext.GetParam1())
Log("call ext.SetParam1:", "#FF0000")
ext.SetParam1(20)
Log("call ext.GetParam1:", ext.GetParam1())
void main() {
Log("call ext::GetParam1:", ext::GetParam1());
Log("call ext::SetParam1:", "#FF0000");
ext::SetParam1(20);
Log("call ext::GetParam1:", ext::GetParam1());
}
Citation
Après avoir vérifié la référence dans la colonne modèle de la page d'édition de la stratégie, enregistrez la stratégie.
Exchange
L'objectif d'échange est considéré par défaut comme le premier objet d'échange ajouté dans les paramètres de stratégie.
Ajout d'objets d'échange dans
Ajout d'objets d'échange sur la page
Les objets d'échange ajoutés correspondent àexchange
les objets du code:
function main() {
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel())
}
def main():
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel())
void main() {
Log("The name of the first exchange object added on the bot page or backtest page:", exchange.GetName(), ", Label:", exchange.GetLabel());
}
Il peut être compris comme un tableau qui stocke tous les objets d'échange commeexchange
les objets d'échange, qui peuvent contenir plusieurs objets d'échange;exchanges[0]
estexchange
.
Les objets d'échange ajoutés correspondent àexchanges[0]
, exchanges[1]
, exchanges[2]
...et ainsi de suite dans le code de la stratégie.
function main() {
for(var i = 0; i < exchanges.length; i++) {
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel())
}
}
def main():
for i in range(len(exchanges)):
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel())
void main() {
for(int i = 0; i < exchanges.size(); i++) {
Log("Index of the exchange object added (the first one is 0 and so on):", i, "Name:", exchanges[i].GetName(), "Label:", exchanges[i].GetLabel());
}
}
L'attributStatus
dans leOrder
structure.
Nom constant | Définition | Valeur |
---|---|---|
Résultats de l'enquête | non terminé | 0 |
- Je ne sais pas. | terminé | 1 |
L'ordre est annulé. | annulé | 2 |
L'ordre est inconnu. | État inconnu (autres États) | 3 |
L'ordre est inconnu.le statut peut appelerexchange.GetRawJSON()
pour obtenir les informations d'état de la commande originale, consulter le fichier d'échange et afficher la description spécifique.
Les noms des constantes du formulaire peuvent être utilisés directement dans le code de stratégie pour comparer avec l'attributStatus
dans leOrder
L'impression de ces noms constants montrera le nombre de fois où les variables sont égales.les noms constantset leur correspondantles valeurs, et d'autres noms constants ci-dessous fonctionnent de la même manière, il n'y aura donc pas de descriptions plus détaillées à leur sujet.
L'attributType
dans leOrder
structure.
Nom constant | Définition | Valeur |
---|---|---|
Nom de l'entreprise | Commande | 0 |
Nom de l'entreprise | Commande de vente | 1 |
L'attributType
dans lePosition
structure.
Nom constant | Définition | Définition | Applicable | Valeur |
---|---|---|---|---|
Résultats de l'analyse | Position à long terme | Utilisation des contrats à terme sur crypto-monnaieexchange.SetDirection("closebuy") pour définir la direction de la position de clôture et fermer ce type de positions |
Futures sur crypto-monnaie | 0 |
PD_SHORT | Position à court terme | Utilisation des contrats à terme sur crypto-monnaieexchange.SetDirection("closesell") pour définir la direction de la position de clôture et fermer ce type de positions |
Futures sur crypto-monnaie | 1 |
L'attributOffset
dans leOrder
structure.
Nom constant | Définition | Valeur |
---|---|---|
Le code de commande est le même. | Les ordres de position ouverts | 0 |
REMARQUE de l'opérateur | Ordre de clôture | 1 |
Dans les codes de stratégie de négociation, les paramètres de stratégie définis sur l'interface de stratégie sont reflétés sous forme de variables globales.JavaScript
L'interface de stratégie permet d'accéder directement aux valeurs de paramètres définies ou modifiées.Python
stratégies, le mot cléglobal
Il est nécessaire de modifier les variables globales de la stratégie.
Type de paramètre:
Variable | Définition | Les commentaires | Le type | Valeur par défaut | Définition |
---|---|---|---|---|---|
Numéro | Type numérique | Les commentaires | Numéro (nombre) | 1 | C++ stratégie est un type de virgule flottante |
Chaîne | une chaîne | Les commentaires | Chaîne (chaîne) | Bonjour FMZ | La valeur par défaut n'a pas besoin d'être citée. L'entrée est traitée comme une chaîne |
Boîte à outils | ComboBox | Les commentaires | ComboBox (sélectionné) | 1|2|3 | La variable combox elle-même est une valeur numérique, qui représente l'index de la colonne sélectionnée par la commande Combobox. |
Bool | Options de vérification | Les commentaires | Boolean (vrai/faux) | vrai | Si elle est vérifiée, la variable bool est vraie; si elle n'est pas vérifiée, la variable bool est fausse |
SecretString est une chaîne | Chaîne chiffrée | Les commentaires | Chaîne chiffrée (chaîne) | Mot de passe | Avec la même utilisation qu'une chaîne, la chaîne cryptée sera envoyée par cryptage et ne sera pas transmise en texte brut |
number
, string
, combox
, bool
, secretString
.Réglage de la dépendance par paramètre:
Un paramètre peut être défini pour permettre à un autre paramètre d'être affiché et caché en fonction de la sélection du paramètre.numberA
, qui est un type numérique.numberA
être affiché ou caché en fonction du paramètreisShowA
(type booléen) est vrai ou faux.numberA
sur les paramètres d'interface tels que:numberA@isShowA
.
De cette façon, si le paramètreisShowA
n'est pas vérifié, le paramètrenumberA
Pour ce qui est des paramètres du type de commande ComboBox, la partie dépendante des paramètres consiste à juger si la valeur du paramètre est égale àvaleur de l'indiceDe la même façon, prendre paramètreisShowA
Lorsque vous définissez les variables dans les paramètres, écrivez:numberA@combox==2
Le paramètrenumberA
affichera ou cachera, selon que le paramètrecombox
sera vérifiée comme étant la troisième option (où l'indice 0 correspond à la première option, l'indice 1 correspond à la deuxième option et l'indice 2 correspond à la troisième option).
Paramètres d'interface de stratégie, commandes interactives et fonction de regroupement de paramètres sur (?First group)
au début de la description du paramètre qui démarre le regroupement, comme indiqué sur la figure suivante:
Lorsque vous utilisez la stratégie, les paramètres sont affichés en groupes:
Enregistrer la valeur par défaut du paramètre:
Les paramètres de stratégie sont montrés sur la figure.Save settings
le bouton après modification des paramètres de stratégie.
Vous pouvez enregistrer les paramètres de stratégie sous forme de code:
/*backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
*/
'''backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
'''
/*backtest
start: 2020-02-29 00:00:00
end: 2020-03-29 00:00:00
period: 1d
args: [["number",2],["string","Hello FMZ.COM"],["combox",2],["bool",false],["numberA@isShowA",666],["isShowA",true]]
*/
Certaines fonctions seront accompagnées de l'originalJSON
Les données demandées pendant l'appel.JSON
les données sont stockées dans l'attributInfo
Puisque le backtest n'est pas pour accéder à une interface de plateforme, les données renvoyées pendant le backtest n'ont pas d'attributInfo
. Voici une description des principaux attributs de chaque structure de données.
Obtenir tout l'historique des transactions (pas lui-même), renvoyé par la fonctionexchange.GetTrades()
.
{
Id : 9585306, // Trading record ID; if the exchange interface does not provide order ID, use the timestamp to fill in
Time : 1567736576000, // Time (Unix timestamp milliseconds)
Price : 1000, // Price
Amount : 1, // Volume
Type : 0 // Order Type; refer to the order type in the constants; 0 is ORDER_TYPE_BUY, meaning the value of ORDER_TYPE_BUY is 0
}
Les cotations de marché sont renvoyées par la fonctionexchange.GetTicker()
.
{
Info : {...}, // After requesting the platform interface, this attribute is not available in the raw data that the exchange interface responds to, during the backtest
High : 1000, // Highest price; if the platform interface does not provide the 24-hour highest price, use sell price 1 to fill in
Low : 500, // Lowest price; if the platform interface does not provide the 24-hour lowest price, use buy price 1 to fill in
Sell : 900, // Sell price 1
Buy : 899, // Buy price 1
Last : 900, // Last executed price
Volume : 10000000, // Recent trading volume; in principle, the unit of spot trading volume is base currency, and the unit of futures trading volume is contract quantity. If the platform interface does not provide this kind of data, use the existing data of the platform interface to fill in; for instance, it might be a trading volume in the unit of quote currency
Time : 1567736576000 // Millisecond-level timestamp
}
La normeOHLC
Cette fonction est utilisée pour tracer des lignes K et pour le calcul et l'analyse des indicateurs de processus.exchange.GetRecords()
renvoie le tableau de structure.Record
la structure représente une barre de ligne k, à savoir une ligne kBAR
LeTime
dans leRecord
est l'heure de début de la période en barres de la ligne K.
{
Time : 1567736576000, // A timestamp, accurate to millisecond, in the same format as the result obtained by Javascript's newDate().GetTime()
Open : 1000, // Open price
High : 1500, // Highest price
Low : 900, // Lowest price
Close : 1200, // Close price
Volume : 1000000 // Trading volume; in principle, the unit of spot trading volume is base currency, and the unit of futures trading volume is contract quantity. If the platform interface does not provide this kind of data, use the existing data of the platform interface to fill in; for instance, it might be a trading volume in the unit of quote currency
}
La structure d'ordre peut être renvoyée par des fonctions, y comprisexchange.GetOrder()
etexchange.GetOrders()
. La fonctionexchange.GetOrders()
renvoie le tableau ou un tableau vide de la structure (s'il n'y a pascommande inachevée en cours, retourner[]
, à savoir un tableau vide).
{
Info : {...}, // After requesting the platform interface, this attribute is not available in the raw data that the exchange interface responds to, during the backtest
Id : 123456, // Unique ide